﻿namespace Contoso.ActiveDirectory {

    #region Usings
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.DirectoryServices;
    using System.Diagnostics;
    using System.Threading; 
    #endregion

    /// <summary>
    /// When querying for a DomainNamingMasterProperties, the base DN must be CN=Partitions, + the Configuration Naming Context at the root domain
    /// </summary>
    [Serializable]
    public class DomainNamingMaster : ADBaseObjectProperties {

        #region Members
        /// <summary>
        /// The DN of the NTDS Settings object of the Server object in the Site -> Configuration container
        /// </summary>
        public string FSMORoleOwner { get; private set; }

        public MSDSBehaviorVersionDefinition MSDSBehaviorVersion { get { return msDSBehaviorVersion; } }
        private MSDSBehaviorVersionDefinition msDSBehaviorVersion;

        public static readonly string ObjectCategoryShortName = "crossRefContainer";
        #endregion

        #region Constructor
        public DomainNamingMaster() {
            this.Initialize();
        } 

        public DomainNamingMaster(DirectoryEntry directoryEntry, bool destroyInputObject = true)
            : base(directoryEntry, destroyInputObject) {
                if (this.GetType().Name == typeof(DomainNamingMaster).Name) {
                this.Attributes = null;
            }
        }

        public DomainNamingMaster(SearchResult result, bool destroyInputObject = true)
            : base(result, destroyInputObject) {
                if (this.GetType().Name == typeof(DomainNamingMaster).Name) {
                this.Attributes = null;
            }
        }

        public DomainNamingMaster(List<string> ldifOutput)
            : base(ldifOutput) {
                if (this.GetType().Name == typeof(DomainNamingMaster).Name) {
                this.Attributes = null;
            }
        }
        #endregion

        #region Methods
        protected override void Initialize() {
            base.Initialize();

            this.FSMORoleOwner = string.Empty;
            msDSBehaviorVersion = MSDSBehaviorVersionDefinition.WIN2008R2;
        }
        protected override void ProcessResults() {

            try {
                base.ProcessResults();

                if (this.Attributes.ContainsKey("fSMORoleOwner")) {
                    this.FSMORoleOwner = this.Attributes["fSMORoleOwner"][0].ToString();
                }
                if (this.Attributes.ContainsKey("msDS-Behavior-Version")) {
                    Enum.TryParse<MSDSBehaviorVersionDefinition>(
                        this.Attributes["msDS-Behavior-Version"][0].ToString(), ignoreCase: true, result: out msDSBehaviorVersion);
                }

                this.IsValid = !string.IsNullOrWhiteSpace(this.DN)
                    && this.ObjectClass.Any(x => string.Equals(x, ObjectCategoryShortName, StringComparison.OrdinalIgnoreCase));            
            }
            catch (Exception e) {
                Debug.WriteLine(string.Format("{0}  [ThreadID: {1}]  {2} Error: {3}", DateTime.Now.TimeOfDay, Thread.CurrentThread.ManagedThreadId, CustomExtensions.CurrentMethodName(), e.VerboseExceptionString()));
                throw;
            }
        } 
        #endregion
    }
}
